#include "stdafx.h"

struct SEffectVertex 
{
	D3DXVECTOR3 position;
	D3DXVECTOR3 normal;
	const static DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
};

void CShaderEffect::Init(LPDIRECT3DDEVICE9 _Device)
{
	LPD3DXBUFFER ErrorBuffer;
	D3DXCreateEffectFromFile(_Device,TEXT("lighteffect.es"),NULL,NULL,D3DXSHADER_DEBUG,NULL,&m_Effect,&ErrorBuffer);
	if (ErrorBuffer)
	{
		const char* ErrorString = (const char*)ErrorBuffer->GetBufferPointer();
		ErrorBuffer = ErrorBuffer;
	}
	m_TechniqueHandle = m_Effect->GetTechniqueByName("lowlevel");

	_Device->CreateVertexBuffer(50*2*sizeof(SEffectVertex),0,SEffectVertex::FVF,D3DPOOL_MANAGED,&m_Vertexs,NULL);

	SEffectVertex* pVectex;
	m_Vertexs->Lock(0,0,(LPVOID*)&pVectex,0);
	for (DWORD i = 0;i < 50;++i)
	{
		FLOAT theta = (2*D3DX_PI*i)/(50-1);
		pVectex[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
		pVectex[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
		pVectex[2*i+0].normal = D3DXVECTOR3( sinf(theta),0, cosf(theta) );
		pVectex[2*i+1].normal = D3DXVECTOR3( sinf(theta),0, cosf(theta) );
	}
	m_Vertexs->Unlock();
}

void CShaderEffect::Render(CEasyRender* _Render)
{
	m_Effect->SetTechnique(m_TechniqueHandle);

	D3DXMATRIXA16 matWorld,matView,matProj,matWorldViewProj;

	D3DXMatrixIdentity(&matWorld);
	matView = *_Render->GetWorld2ViewMatrix();
	matProj = *_Render->GetProjectorMatrix();

	matWorldViewProj = matWorld * matView * matProj;

	D3DXVECTOR4 vecEyePos = *_Render->GetEyePosition();
	D3DXVECTOR4 lightDir = D3DXVECTOR4( cosf(timeGetTime()/350.0f), 1.0f,
		sinf(timeGetTime()/350.0f), 1.0f );
	m_Effect->SetVector( "vecLightDir", &lightDir );
	m_Effect->SetVector( "vecEyePos",&vecEyePos);

	m_Effect->SetMatrix("matWorldViewProj",&matWorldViewProj);
	m_Effect->SetMatrix("matWorld",&matWorld);

	D3DXVECTOR4 mtrlAmbientInEffect  = D3DXVECTOR4( 0.5f, 0.5f, 0.0f, 1.0f );
	D3DXVECTOR4 mtrlDiffuseInEffect  = D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f );
	D3DXVECTOR4 mtrlSpecularInEffect = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
	m_Effect->SetVector( "materialAmbient",  &mtrlAmbientInEffect );
	m_Effect->SetVector( "materialDiffuse",  &mtrlDiffuseInEffect );
	m_Effect->SetVector( "materialSpecular", &mtrlSpecularInEffect);

	DWORD PassCount = 0;
	m_Effect->Begin((UINT*)&PassCount,0);
	for (DWORD index = 0;index < PassCount;++index)
	{
		m_Effect->BeginPass(index);

		_Render->GetDevice()->SetStreamSource(0,m_Vertexs,0,sizeof(SEffectVertex));
		_Render->GetDevice()->SetFVF(SEffectVertex::FVF);
		_Render->GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,50*2 - 2);
		m_Effect->EndPass();
	}
	m_Effect->End();
}

struct STextureVertex 
{
	D3DXVECTOR3 position;
	float u,v;
	const static DWORD FVF = D3DFVF_TEX1 | D3DFVF_XYZ;
};

void CTextureEffect::Init(LPDIRECT3DDEVICE9 _Device)
{
	_Device->CreateVertexBuffer(50 * 2 * sizeof(STextureVertex),0,STextureVertex::FVF,
		D3DPOOL_MANAGED,&m_Vertexs,NULL);

	STextureVertex* pVertex;
	m_Vertexs->Lock(0,0,(LPVOID*)&pVertex,0);
	for (DWORD i = 0;i < 50;++i)
	{
		FLOAT theta = (2*D3DX_PI*i)/(50-1);
		pVertex[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
		pVertex[2*i+0].u       = ((FLOAT)i)/(50-1);
		pVertex[2*i+0].v       = 1.0f;

		pVertex[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
		pVertex[2*i+1].u       = ((FLOAT)i)/(50-1);
		pVertex[2*i+1].v       = 0.0f;
	}
	m_Vertexs->Unlock();
	D3DXCreateTextureFromFile(_Device,TEXT("texture.jpg"),&m_Texture);

	LPD3DXBUFFER ErrorBuffer;
	D3DXCreateEffectFromFile(_Device,TEXT("textureeffect.es"),NULL,NULL,D3DXSHADER_DEBUG,NULL,&m_Effect,&ErrorBuffer);
	if (ErrorBuffer)
	{
		const char* ErrorString = (const char*)ErrorBuffer->GetBufferPointer();
		ErrorBuffer = ErrorBuffer;
	}

	m_TechniqueHandle = m_Effect->GetTechniqueByName("EffectTexture");
}

void CTextureEffect::Render(CEasyRender* _Render)
{
	m_Effect->SetTexture("effecttexture",m_Texture);
	UINT dwIndex;
	m_Effect->SetTechnique(m_TechniqueHandle);

	D3DXMATRIXA16 matWorldViewProj;
	D3DXMATRIX matWorld,matView,matProj;

	D3DXMatrixIdentity(&matWorld);
	matView = *_Render->GetWorld2ViewMatrix();
	matProj = *_Render->GetProjectorMatrix();

	matWorldViewProj = matWorld * matView * matProj;
	m_Effect->SetMatrix("matWorldViewProj",&matWorldViewProj);

	m_Effect->Begin(&dwIndex,0);
	for (UINT index = 0;index < dwIndex;++index)
	{
		m_Effect->BeginPass(index);
		_Render->GetDevice()->SetStreamSource(0,m_Vertexs,0,sizeof(STextureVertex));
		_Render->GetDevice()->SetFVF(STextureVertex::FVF);
		_Render->GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,50 * 2 - 2);
		m_Effect->EndPass();
	}
	m_Effect->End();
}